package com.seeyon.apps.quartz.job;

import cn.hutool.core.convert.Convert;
import com.seeyon.apps.attendance.manager.AttendanceSettingManager;
import com.seeyon.apps.quartz.abstra.AbstractQuartzTask;
import com.seeyon.cap4.batch.params.BatchRefreshParams;
import com.seeyon.cap4.batch.service.CAPBatchRefreshService;
import com.seeyon.cap4.form.bean.FormBean;
import com.seeyon.cap4.form.bean.FormDataMasterBean;
import com.seeyon.cap4.form.bean.FormDataSubBean;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.authenticate.domain.User;
import com.seeyon.ctp.common.base.result.ServiceResult;
import com.seeyon.ctp.common.content.mainbody.MainbodyManager;
import com.seeyon.ctp.common.filemanager.manager.AttachmentManager;
import com.seeyon.ctp.common.usermessage.UserMessageManager;
import com.seeyon.ctp.login.UserUtil;
import com.seeyon.ctp.util.JDBCAgent;
import org.apache.commons.lang.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.seeyon.apps.leaveRecord.util.CAP4FormKit.setCellValue;
import static com.seeyon.apps.leaveRecord.util.EnumUtils.getEnumItemId;
import static com.seeyon.apps.leaveRecord.util.EnumUtils.getEnumItemName;
import static com.seeyon.apps.quartz.util.CAP4FormKit.*;

/**
 * @Author: SPK
 * @Date: 2022/6/21 15:15
 * @Description:
 */
public class UpdateRecordJob extends AbstractQuartzTask {
    private AttachmentManager attachmentManager;
    private MainbodyManager ctpMainbodyManager;
    private UserMessageManager userMessageManager;
    private CAPBatchRefreshService capBatchRefreshService;
    private AttendanceSettingManager attendanceSettingManager;
    private static boolean On = false;

    public static boolean isOn() {
        return On;
    }

    public void setAttendanceSettingManager(AttendanceSettingManager attendanceSettingManager) {
        this.attendanceSettingManager = attendanceSettingManager;
    }
    private MainbodyManager getCtpMainbodyManager() {
        if (null == ctpMainbodyManager) {
            ctpMainbodyManager = (MainbodyManager) AppContext.getBean("ctpMainbodyManager");
        }
        return ctpMainbodyManager;
    }

    public AttachmentManager getAttachmentManager() {
        if (null == attachmentManager) {
            attachmentManager = (AttachmentManager) AppContext.getBean("attachmentManager");
        }
        return attachmentManager;
    }

    public void setUserMessageManager(UserMessageManager userMessageManager) {
        this.userMessageManager = (UserMessageManager) AppContext.getBean("userMessageManager");
    }


    @Override
    public String taskRun(String param) throws Exception {
        On = true;
        ArrayList<String> masterIds = new ArrayList<>();
        FormBean leaveRecord = getFormApi4Cap4().getFormByFormCode("leaveRecord");
        Calendar instance = Calendar.getInstance();
        int year = instance.get(Calendar.YEAR);
        try (JDBCAgent agent = new JDBCAgent(true, false)) {
            User user = UserUtil.build("dsz", "", null);
            if (user != null) {
                UserUtil.setCurrentUser(user);
            }
            String tableName = leaveRecord.getMasterTableBean().getTableName();
            String nowYear = getFieldTaleId(leaveRecord, "当前年度");
            String params = "select id from " +tableName+" where "+nowYear+ " = ?";
            agent.execute(params, getEnumItemId("年度", year + "年"));
            List<Map<String, Object>> list = agent.resultSetToList();
            if (null != list && list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    FormDataMasterBean leaveMasterBean = getFormApi4Cap4().findDataById(Convert.toLong(list.get(i).get("id")), leaveRecord.getId(), null);
                    masterIds.add(leaveMasterBean.getId().toString());
                    List<FormDataSubBean> subBeans = getSubBeans(leaveMasterBean, "请假明细");
                    Double days = Double.valueOf(getFieldStrValue(leaveMasterBean, "本年剩余年休假天数")) * 2;
                    ArrayList<FormDataSubBean> rangeList = new ArrayList<>();
                    //排序
                    Bsort(subBeans);

                    if (days > 0) {

                        for (int j = 0; j < subBeans.size(); j++) {
                            FormDataSubBean subBean = subBeans.get(j);
                            String type = getEnumItemName(getSubFieldStrValue(subBean, "请假类型"));
                            String rbLink = getSubFieldStrValue(subBean, "销假链接");
                            if ("年休假".equals(type) || "事假".equals(type) && StringUtils.isBlank(rbLink)) {
                                rangeList.add(subBean);
                            }
                        }
                        ArrayList<Integer> counts = new ArrayList<>();
                        int a = 1;
                        int b = 0;
                        for (int j = 0; j < rangeList.size() - 1; j++) {
                            if(j==34){
                                System.out.println(1);
                            }
                            FormDataSubBean subBeanA = rangeList.get(j);
                            FormDataSubBean subBeanB = rangeList.get(j + 1);
                            Date startTimeA = (Date) getSubFieldValue(subBeanA, "请假开始时间");
                            String startNoonA = getEnumItemName(getSubFieldStrValue(subBeanA, "请假开始时间-上下午"));
                            Date startTimeB = (Date) getSubFieldValue(subBeanB, "请假开始时间");
                            String startNoonB = getEnumItemName(getSubFieldStrValue(subBeanB, "请假开始时间-上下午"));
                            String typeA = getEnumItemName(getSubFieldStrValue(subBeanA, "请假类型"));
                            String typeB = getEnumItemName(getSubFieldStrValue(subBeanB, "请假类型"));

                            int dayCount = getDayCount(startTimeB, startTimeA);
                            if (dayCount == 0 || (dayCount == 1 && "下午".equals(startNoonA) && "上午".equals(startNoonB))) {
                                a++;
                                if (!counts.contains(j)) {
                                    if (typeA.equals("事假")) {
                                        b++;
                                        counts.add(j);
                                    }
                                }
                                if (!counts.contains(j + 1)) {
                                    if (typeB.equals("事假")) {
                                        b++;
                                        counts.add(j + 1);
                                    }
                                }
                                if (j == rangeList.size() - 2 && a >= 4) {
                                    if (days >= b) {
                                        days = days - b;
                                        for (int k = 0; k < counts.size(); k++) {
                                            setType(rangeList,subBeans, counts, k);
                                        }
                                    } else {
                                        for (int k = 0; k < days; k++) {
                                            setType(rangeList,subBeans, counts, k);
                                        }
                                        days = 0.0;
                                    }
                                    a=1;
                                    b=0;
                                    counts.clear();

                                }
                            } else if (a >= 4) {
                                if (days >= b) {
                                    days = days - b;
                                    for (int k = 0; k < counts.size(); k++) {
                                        setType(rangeList,subBeans, counts, k);
                                    }
                                } else {
                                    for (int k = 0; k < days; k++) {
                                        setType(rangeList,subBeans, counts, k);
                                    }
                                    days = 0.0;
                                }
                                a=1;
                                b=0;
                                counts.clear();

                            } else {
                                a = 1;
                                b = 0;
                                counts.clear();
                            }

                        }
                    }

                    leaveMasterBean.setSubData("formson_0058", subBeans);
                    try {
                        getFormApi4Cap4().saveOrUpdateFormData(leaveMasterBean, leaveRecord.getId(), true);
                    } catch (Exception e) {
                        log.error("保存正文数据异常：", e);
                    }
                    //刷新
                }

                BatchRefreshParams batchRefreshParams = new BatchRefreshParams();
                batchRefreshParams.setFormId(leaveRecord.getId());
                batchRefreshParams.setSize(masterIds.size());
                batchRefreshParams.setMasterIds(masterIds);
                batchRefreshParams.setExecuteRelation(true);
                leaveRecord.getBind().getUnFlowTemplateMap().keySet().forEach(element -> {
                    Long authId = leaveRecord.getBind().getUnFlowTemplateMap().get(element).getId();
                    batchRefreshParams.setBindAuthId(authId);
                });
                this.capBatchRefreshService = (CAPBatchRefreshService) AppContext.getBean("capBatchRefreshService");
                ServiceResult<?> serviceResult = capBatchRefreshService.batchRefresh(batchRefreshParams);
                log.info("自动生成收款计划刷新结果:" + serviceResult.getMessage());
            }
        } catch (Exception e) {
            log.error("定时更新假勤档案失败", e);
        }
        On = false;
        return "定时更新假勤档案成功";
    }

    private void setType(List<FormDataSubBean> rangeList,List<FormDataSubBean> subBeans, ArrayList<Integer> counts, int k) {
        FormDataSubBean subBean = rangeList.get(counts.get(k));
        setCellValue(subBean, "请假类型", getEnumItemId("请假类型", "年休假"));
        subBeans.set(subBean.getSort()-1, subBean);
    }

    /**
     * 明细行排序
     *
     * @param arr
     */
    public static void Bsort(List<FormDataSubBean> arr) {
        FormDataSubBean temp;
        for (int i = 0; i < arr.size() - 1; i++) {
            for (int j = 0; j < arr.size() - i - 1; j++) {
                FormDataSubBean before = arr.get(j);
                Date startTimeA = (Date) getFieldValue(before, "请假开始时间");
                String startNoonA = getEnumItemName(getSubFieldStrValue(before, "请假开始时间-上下午"));
                FormDataSubBean after = arr.get(j + 1);
                Date startTimeB = (Date) getFieldValue(after, "请假开始时间");
                String startNoonB = getEnumItemName(getSubFieldStrValue(after, "请假开始时间-上下午"));
                if ((startTimeA.compareTo(startTimeB) > 0) || (startTimeA.compareTo(startTimeB) == 0 && startNoonA.equals("下午"))) {
                    temp = arr.get(j);
                    temp.setSort(j + 1);
                    setCellValue(temp, "序号", j + 1);
                    FormDataSubBean subBean = arr.get(j + 1);
                    subBean.setSort(j);
                    setCellValue(subBean, "序号", j);
                    arr.set(j, subBean);
                    arr.set(j + 1, temp);
                }
            }
        }
    }

    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     *
     * @param date1
     * @param date2
     * @return
     */
    private int getDayCount(Date date1, Date date2) throws ParseException {
        SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyyMMdd");
        int days = (int) ((date1.getTime() - date2.getTime()) / (1000 * 3600 * 24));
        return days;
    }

    private Date CalToDate(Date date1) {
        Calendar date = Calendar.getInstance();
        date.setTime(date1);
        int year = date.get(Calendar.YEAR);
        int mouth = date.get(Calendar.MONTH);
        int day = date.get(Calendar.DATE);
        Calendar data2 = Calendar.getInstance();
        data2.set(year, mouth, day, 23, 59, 59);
        return data2.getTime();
    }
}
